package com.ledim.adapter.base;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.os.Build;
import android.os.Handler;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewStub;
import android.widget.ImageView;
import android.widget.TextView;
import com.ledim.utils.ConstantUtil;
import com.ledim.utils.FrescoUtil;
import com.ledim.utils.LedimNetWorkUtils;
import com.ledim.widget.ptr.LedimListViewStateView;
import com.ledim.widget.ptr.PtrClassicFrameLayout;
import com.ledim.widget.ptr.PtrDefaultHandler;
import com.ledim.widget.ptr.PtrFrameLayout;
import com.ledim.widget.ptr.PtrHandler;
import com.ledim.widget.ptr.header.LedimListViewHeader;
import com.ledim.widget.recyclerview.BaseQuickAdapter;
import com.ledim.widget.recyclerview.loadmore.LoadMoreView;
import com.letv.android.young.client.R;
import java.util.List;

import static android.view.View.GONE;
import static android.view.View.VISIBLE;

/**
 * Created by ccx on 16/12/5.
 * Rv 下拉刷新和上拉加载数据处理基类
 */

public abstract class BaseRvDataPresenter {

    public RecyclerView mRvList;
    public BaseQuickAdapter mAdapter;
    protected int mCurrPage = 0;// 当前页
    public int mLoadPage = 0;// loading的页
    public final static int TYPE_PULL_REFRESH = 0; //下拉刷新
    public final static int TYPE_LOAD_MORE = TYPE_PULL_REFRESH + 1;//上拉加载
    public final static int TYPE_NORMAL_REFRESH = TYPE_LOAD_MORE + 1;//正常刷新 无上拉和加载动画
    private int mRefreshType = TYPE_NORMAL_REFRESH;
    /**
     * mEnablePtr 是否允许下拉刷新
     * mEnableLoadMore 是否允许上拉加载
     */
    private boolean mEnablePtr, mEnableLoadMore;
    /**
     * 下拉刷新控件
     */
    protected PtrClassicFrameLayout mRefreshView;
    private Activity mActivity;
    private View mFragmentView;
    /**
     * 各种状态的view，包括loading,server_error,no_net,no_data
     */
    protected LedimRvStateController mSateController;

    public BaseRvDataPresenter(Activity activity, BaseQuickAdapter adapter, RecyclerView rvList) {
        mActivity = activity;
        mRvList = rvList;
        initRvAdapter(adapter);
    }

    public BaseRvDataPresenter(View contentView, BaseQuickAdapter adapter, RecyclerView rvList) {
        mFragmentView = contentView;
        mRvList = rvList;
        initRvAdapter(adapter);
    }

    private LedimRvStateController getSateController() {
        if (mSateController == null) {
            ViewStub stub = (ViewStub) getRvParentView().findViewById(R.id.view_state_vs);
            mSateController = new LedimRvStateController(stub.inflate());
            mSateController.setOnRetryListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    refresh(TYPE_NORMAL_REFRESH);
                }
            });
        }
        return mSateController;
    }

    public void initLoadMoreView(LoadMoreView moreView) {
        mEnableLoadMore = true;
        mAdapter.setEnableLoadMore(true);
        mAdapter.setLoadMoreView(moreView);
        mAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {

            @Override
            public void onLoadMoreRequested() {
                //获取下一页
                refresh(TYPE_LOAD_MORE);
            }
        });
    }

    /**
     * 初始化adapter
     */
    @TargetApi(Build.VERSION_CODES.M)
    private void initRvAdapter(BaseQuickAdapter adapter) {
        mAdapter = adapter;
        mRvList.setAdapter(mAdapter);
        mRvList.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                switch (newState) {

                    case RecyclerView.SCROLL_STATE_IDLE:
                        //设置要加载图片的起始位置和结束位置
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                FrescoUtil.resume();//解除锁定
                            }
                        }, 1000);
                        break;
                    default:
                        FrescoUtil.pause();//处于滚动状态锁定图片加载线程
                        break;

                }

            }
        });
    }

    /**
     * @return
     * 返回父view
     * activity 返回decoview
     * fragment 返回fragment view
     */
    private View getRvParentView() {
        if (mFragmentView != null) {
            return mFragmentView;
        }
        return mActivity.getWindow().getDecorView();
    }

    /**
     * 初始化下拉刷新UI
     */
    public void initRefreshView() {
        mEnablePtr = true;
        mRefreshView = (PtrClassicFrameLayout) getRvParentView().findViewById(R.id.ptr_view);
        // 以下设置大都可在xml中设置
        // 设置阻尼系数
        // ptr.setResistance(1.7f);
        // // 触发刷新时移动的位置比例，默认，1.2f，移动达到头部高度 1.2 倍时可触发刷新操作。

        // // 回弹延时，默认 200ms，回弹到刷新高度所用时间
        // ptr.setDurationToClose(200);
        // // 头部回弹时间，默认 1000ms。
        // ptr.setDurationToCloseHeader(1000);
        // // 设置下拉达到高度后自动刷新（默认释放刷新）
        // ptr.setPullToRefresh(false);
        // // 刷新是否保持头部，默认值 true
        // ptr.setKeepHeaderWhenRefresh(true);
        // 自定义headerview
        mRefreshView.setRatioOfHeaderHeightToRefresh(1.2f);
        LedimListViewHeader header = new LedimListViewHeader(getContext());
        mRefreshView.setHeaderView(header);
        mRefreshView.addPtrUIHandler(header);
        mRefreshView.setPtrHandler(new PtrHandler() {
            @Override
            public boolean checkCanDoRefresh(PtrFrameLayout ptrFrameLayout, View view,
                                             View header) {
                return PtrDefaultHandler.checkContentCanBePulledDown(ptrFrameLayout, mRvList, header);
            }

            @Override
            public void onRefreshBegin(PtrFrameLayout ptrFrameLayout) {
                refresh(TYPE_PULL_REFRESH);
            }
        });
    }

    /**
     * 设置返回错误信息
     */
    public void onErrResponse() {
        switch (mRefreshType) {
            case TYPE_PULL_REFRESH:
            case TYPE_NORMAL_REFRESH:
                if (mRefreshType == TYPE_PULL_REFRESH) {
                    mRefreshView.refreshComplete();
                }
                if (!LedimNetWorkUtils.isNetworkAvailable(getContext())) {
                    getSateController().setState(LedimListViewStateView.STATE_NO_NET);
                } else {
                    getSateController().setState(LedimListViewStateView.STATE_SERVER_ERROR);
                }
                mRvList.setVisibility(GONE);
                break;
            case TYPE_LOAD_MORE:
                if (mEnablePtr) {
                    mRefreshView.setEnabled(true);
                }
                mAdapter.loadMoreFail();
                break;
        }

    }

    /**
     * 如果使用服务器hasmore字段，就必须调用这个方法（推荐使用如果可以）
     *
     * @param list
     *         当数据异常得到的list为null时，setDatas(null)即可
     * @param hasMore
     *         是否有更多（来自服务器的字段）
     */
    public void setData(List list, boolean hasMore) {
        if (list == null || list.isEmpty()) {
            //无数据
            switch (mRefreshType) {
                case TYPE_PULL_REFRESH:
                case TYPE_NORMAL_REFRESH:
                    if (mRefreshType == TYPE_PULL_REFRESH) {
                        mRefreshView.refreshComplete();
                    }
                    getSateController().setState(LedimListViewStateView.STATE_NO_DATA);
                    mRvList.setVisibility(GONE);
                    break;
                case TYPE_LOAD_MORE:
                    // 加载更多，证明已经有数据了，并不清空已有数据，不设置error状态
                    mLoadPage = mCurrPage;
                    mAdapter.loadMoreFail();
                    break;
            }

        } else {
            if (mRvList.getVisibility() == GONE) {
                mRvList.setVisibility(VISIBLE);
            }
            //有数据
            switch (mRefreshType) {
                case TYPE_PULL_REFRESH:

                    mRefreshView.refreshComplete();
                    mAdapter.setNewData(list);
                    break;
                case TYPE_LOAD_MORE:
                    mAdapter.addData(list);
                    mCurrPage++;
                    if (hasMore) {
                        mAdapter.loadMoreComplete();
                    } else {
                        mAdapter.loadMoreEnd();
                    }
                    break;
                case TYPE_NORMAL_REFRESH:
                    getSateController().setState(LedimListViewStateView.STATE_NORMAL);
                    mAdapter.setNewData(list);
                    break;
            }
            mAdapter.notifyDataSetChanged();
            // mLedimStateView.setState(LedimListViewStateView.STATE_NORMAL);
            //loadMoreFinish(STATE_NORMAL, hasMore);
        }

        if (mEnableLoadMore && mRefreshType == TYPE_PULL_REFRESH) {
            mAdapter.setEnableLoadMore(false);
        }
        if (mEnablePtr && mRefreshType == TYPE_LOAD_MORE) {
            mRefreshView.setEnabled(true);
        }
    }

    /**
     * 初次进入刷新
     */
    public void enterRefresh() {
        refresh(TYPE_NORMAL_REFRESH);
    }

    /**
     * 下拉刷新
     */
    public void pullRefresh() {
        refresh(TYPE_PULL_REFRESH);
    }

    /**
     * 刷新方法
     *
     * @param refreshType
     *         刷新类型
     *         下拉刷新
     *         点击stateview刷新或者正常加载
     *         上拉加载更多
     */
    public void refresh(int refreshType) {
        mRefreshType = refreshType;
        switch (mRefreshType) {
            case TYPE_PULL_REFRESH:
                //下拉刷新时 若上拉加载开关打开，暂时禁止上拉加载
                if (mEnableLoadMore) {
                    mAdapter.setEnableLoadMore(false);
                }
                mLoadPage = 0;
                mCurrPage = 0;
                break;
            case TYPE_LOAD_MORE:
                //上拉加载时 若下拉刷新开关是打开的，暂时禁止下拉刷新
                if (mEnablePtr) {
                    mRefreshView.setEnabled(false);
                }
                mLoadPage++;
                break;
            case TYPE_NORMAL_REFRESH:
                mRvList.setVisibility(GONE);
                getSateController().setState(LedimListViewStateView.STATE_LOADING);
                break;
        }
        getData();
        //if (refreshType == TYPE_PULL_REFRESH) {
        //    mLedimStateView.setState(LedimListViewStateView.STATE_OTHER);
        //} else {
        //    mLedimStateView.setState(LedimListViewStateView.STATE_LOADING);
        //}
    }

    public int getPageSize() {
        return ConstantUtil.PAGE_SIZE;
    }

    public int getItemCount() {
        return mAdapter.getItemCount();
    }

    /**
     * stateView控制类
     */
    class LedimRvStateController {

        public static final byte STATE_NORMAL = 0;
        public static final byte STATE_NO_NET = 1;
        public static final byte STATE_SERVER_ERROR = 2;
        public static final byte STATE_NO_DATA = 4;
        public static final byte STATE_LOADING = 5;
        /**
         * 其他状态，如ptr的refresh与加载更多，效果
         */
        public static final byte STATE_OTHER = 7;

        private byte state;

        private View ll_state_view;
        private ImageView iv_hint;
        private TextView tv_hint;
        private View ll_loading;

        private int imgNoNetId, imgNoDataId, imgSEId;
        private int hintNoNetId, hintNoDataId, hintSEId;
        private AnimationDrawable animationDrawable = null;

        /**
         * @param textId
         *         设置无数据文案
         */
        public void setNoDataText(int textId) {
            if (textId != 0) {
                hintNoDataId = textId;
            }
        }

        public LedimRvStateController(View view) {
            initView(view);
        }

        /**
         * 初始化资源
         */
        private void initRes() {
            imgNoNetId = R.drawable.img_no_net;
            imgSEId = imgNoDataId = R.drawable.img_no_data;
            hintNoNetId = R.string.str_no_net;
            hintSEId = R.string.str_server_error;
            hintNoDataId = R.string.str_nodata_error;
        }

        private void initView(View view) {
            ll_loading = view.findViewById(R.id.ll_loading);
            // loading_text.setVisibility(GONE);
            ImageView loadingImage = (ImageView) view.findViewById(R.id.progress_view);
            loadingImage.setImageResource(R.anim.loading_animation);
            animationDrawable = (AnimationDrawable) loadingImage.getDrawable();
            animationDrawable.setOneShot(false);
            ll_state_view = view.findViewById(R.id.ll_state_view);
            iv_hint = (ImageView) ll_state_view.findViewById(R.id.iv_stateview_icon);
            tv_hint = (TextView) ll_state_view.findViewById(R.id.tv_stateview_hint);
            initRes();
            setState(STATE_NORMAL);
        }

        public int getState() {
            return state;
        }

        public void setState(byte state) {
            this.state = state;
            switch (state) {
                case STATE_NO_NET:
                    showStateView(imgNoNetId, hintNoNetId);
                    break;
                case STATE_SERVER_ERROR:
                    showStateView(imgSEId, hintSEId);
                    break;
                case STATE_NO_DATA:
                    showStateView(imgNoDataId, hintNoDataId);
                    break;
                // case STATE_LOADING:
                // showStateView(-1, -1, -1);
                // break;
                default:
                    showStateView(-1, -1);
                    break;
            }
        }

        private void showStateView(int imgId, int hintId) {
            if (animationDrawable != null) {
                animationDrawable.stop();
            }
            if (state == STATE_NORMAL) {
                ll_state_view.setVisibility(GONE);
                ll_loading.setVisibility(GONE);
            } else if (state == STATE_OTHER) {
                ll_state_view.setVisibility(GONE);
                ll_loading.setVisibility(GONE);
            } else if (state == STATE_LOADING) {
                ll_state_view.setVisibility(GONE);
                if (animationDrawable != null) {
                    animationDrawable.start();
                }
                ll_loading.setVisibility(VISIBLE);
            } else {
                ll_loading.setVisibility(GONE);
                ll_state_view.setVisibility(VISIBLE);
                if (imgId != -1) {
                    iv_hint.setImageResource(imgId);
                    iv_hint.setVisibility(VISIBLE);
                } else {
                    iv_hint.setVisibility(GONE);
                }
                if (hintId == -1) {
                    tv_hint.setVisibility(GONE);
                } else {
                    tv_hint.setText(hintId);
                    tv_hint.setVisibility(VISIBLE);
                }
            }

        }

        public void setOnRetryListener(View.OnClickListener onRetryListener) {
            ll_state_view.setOnClickListener(onRetryListener);
        }
    }

    private Context getContext() {
        return mFragmentView == null ? mActivity : mFragmentView.getContext();
    }

    public abstract void getData();
}
